// 子类必须调用在construcctor中调用super方法
{
  class Point {}
  class Color extends Point {
    constructor () {
      super()
    }
  }
  const col = Reflect.construct(Color, [])
  console.log(col) // Color {}
  console.log('Point', typeof Point) // function
  console.log('Color', typeof Color) // function
}


// 让constructor取默认值，默认调用super
{
  class Point {}
  class Color extends Point {}
  const col = Reflect.construct(Color, [])
  console.log(col) // Color {}
}

// super作为函数
{
  class A {
    constructor () {
      console.log(new.target.name)
    }
  }
  class B extends A {
    constructor () {
      super()
    }
  }
  new A() // A
  new B() // B
}

// super作为对象
{
  class A {
    constructor () {
      this.g = 'g'
    }
    p () {
      return 2
    }
  }
  class B extends A {
    constructor () {
      super()
      console.log(super.p()) // 2
      console.log(super.g) // undefined  super指向父类原型，实例上的属性方法访问不到
    }
  }
  new B() // 2
}

// 子类通过super调用父类方法，父类方法中的this指向子类
{
  class A {
    constructor () {
      this.x = 1
    }
    print () {
      console.log(this.x)
    }
  }
  class B extends A {
    constructor () {
      super()
      this.x = 2
    }
    m () {
      super.print()
    }
  }
  let b = new B()
  b.m() // 2
}

// 通过super调用某个属性赋值
{
  class A {
    constructor () {
      this.x = 1
    }
  }
  class B extends A {
    constructor () {
      super()
      this.x = 2
      super.x = 3 // 赋值操作，super就是this
      console.log(super.x) // 取值操作，super指向父类的原型对象 原型对象上没有x, undefined
      console.log(this.x) // 3
    }
  }
  let b = new B()
}

// super作为对象，用在静态方法中，这是super指向父类
{
  class A {
    static myMethod(msg) {
      console.log('static', msg)
    }
    myMethod (msg) {
      console.log('instance', msg)
    }
  }
  class B extends A {
    static myMethod (msg) {
      super.myMethod(msg) // super用作对象用在静态方法中
    }
    myMethod (msg) {
      super.myMethod(msg)
    }
  }
  B.myMethod(1) // static 1

  const b = new B()
  b.myMethod(2) // instance 2
}

{
  const obj = {
    a: 1,
    b: 2,
    c: 3,
    [Symbol.iterator] () {
      let index = 0
      return {
        next: function () {
          index ++
          if (index < 3) {
            return {value: index, done: false}
          }
          return {value: undefined, done: true}
        }
      }
    }
  }
  console.log({...obj}) // { a: 1, b: 2, c: 3 }
  console.log([...obj]) // [ 1, 2 ]
}